package com.mindspore.federatedime.ui;

import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.huawei.flclient.AsyncFLJob;
import com.huawei.flclient.EarlyStopMod;
import com.huawei.flclient.LiteTrain;
import com.mindspore.federatedime.R;
import com.mindspore.federatedime.adapter.ChatAdapter;
import com.mindspore.federatedime.adapter.EmojiAdapter;
import com.mindspore.federatedime.bean.EmojiBean;
import com.mindspore.federatedime.bean.ImageMsgBody;
import com.mindspore.federatedime.bean.Message;
import com.mindspore.federatedime.bean.MsgSendStatus;
import com.mindspore.federatedime.bean.MsgType;
import com.mindspore.federatedime.bean.TextMsgBody;
import com.mindspore.federatedime.util.ChatUiHelper;
import com.mindspore.federatedime.util.EmojiUtils;
import com.mindspore.federatedime.util.FileUtils;
import com.mindspore.federatedime.util.LabelUtils;
import com.mindspore.federatedime.widget.StateButton;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.UUID;

public class ChatActivity extends AppCompatActivity {

    private static final String MODELPATH = "albert.ms";
    private ByteBuffer modelPathBuf;
    private LinearLayout mLlContent;
    private RecyclerView mRvChat;
    private RecyclerView mRvEmoji;
    private EditText mEtContent;
    private StateButton mBtnSend;
    private TextView trainBtn;

    private ChatAdapter chatAdapter;
    private EmojiAdapter emojiAdapter;

    private List<Message> dataList = new ArrayList<>();
    private List<EmojiBean> emojiList = new ArrayList<>();
    private List<String> txtList = new ArrayList<>();

    private AsyncFLJob asyncFLJob;
    private Random random;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);
        init();
        asyncFLJob = new AsyncFLJob();
        modelPathBuf = LabelUtils.loadModelFile(this, MODELPATH);
        random = new Random(1);
    }

    private void init() {
        mLlContent = findViewById(R.id.llContent);
        mRvChat = findViewById(R.id.rv_chat_list);
        mRvEmoji = findViewById(R.id.emoji_recycle);
        mEtContent = findViewById(R.id.et_content);
        mBtnSend = findViewById(R.id.btn_send);
        trainBtn = findViewById(R.id.trainBtn);

        chatAdapter = new ChatAdapter(this, dataList);
        LinearLayoutManager mLinearLayout = new LinearLayoutManager(this);
        mRvChat.setLayoutManager(mLinearLayout);
        mRvChat.setAdapter(chatAdapter);
        initChatUi();

        emojiAdapter = new EmojiAdapter(this, emojiList);
        LinearLayoutManager mHorizontalLinearLayout = new LinearLayoutManager(this, RecyclerView.HORIZONTAL, false);
        mRvEmoji.setLayoutManager(mHorizontalLinearLayout);
        mRvEmoji.setAdapter(emojiAdapter);
        emojiAdapter.setOnItemClickListener(position -> {
            sendImageMessage(emojiList.get(position).getValue());
            txtList.add(LabelUtils.generateLabelString(mEtContent.getText().toString(), emojiList.get(position).getId()));
            mEtContent.setText("");
            mRvEmoji.setVisibility(View.GONE);

        });

        mBtnSend.setOnClickListener(view -> {
            sendTextMsg(mEtContent.getText().toString());
            mRvEmoji.setVisibility(View.GONE);
            mEtContent.setText("");
        });

        trainBtn.setOnClickListener(view -> {
            train();
        });


        mEtContent.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                if (!TextUtils.isEmpty(editable.toString())) {
                    mRvEmoji.setVisibility(View.VISIBLE);
                    showImage(editable.toString());
                }else {
                    mRvEmoji.setVisibility(View.GONE);
                }
            }
        });
    }


    private void initChatUi() {
        final ChatUiHelper mUiHelper = ChatUiHelper.with(this);
        mUiHelper.bindContentLayout(mLlContent)
                .bindttToSendButton(mBtnSend)
                .bindEditText(mEtContent);
        mRvChat.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
            if (bottom < oldBottom) {
                mRvChat.post(() -> {
                    if (chatAdapter.getItemCount() > 0) {
                        mRvChat.smoothScrollToPosition(chatAdapter.getItemCount() - 1);
                    }
                });
            }
        });

        mRvChat.setOnTouchListener((view, motionEvent) -> {
            mUiHelper.hideSoftInput();
            mEtContent.clearFocus();
            return false;
        });
    }


    private void showImage(String content) {
        int[]  label = asyncFLJob.modelInferenceSingleDataFromBuffer(
                    content, modelPathBuf, LabelUtils.getJson2Array(this), 1, 5);
        Log.e("AAA", "content》》" + content + ">>>label" + Arrays.toString(label));
        emojiList.clear();
        emojiList.addAll(EmojiUtils.getEmojiImage(label));
        emojiAdapter.notifyDataSetChanged();
    }


    private void train() {
        if (txtList.size() > 0) {
            FileUtils.writeToTxt("federated.tsv", txtList);
        }

        LiteTrain train = LiteTrain.getInstance();
        train.initFromBuffer(modelPathBuf, 1);
        train.setAlbertInput(Environment.getExternalStorageDirectory().getPath() + "/" + "federated.tsv", LabelUtils.getJson2Array(ChatActivity.this));
        int status = train.trainAlbert(16, 5, EarlyStopMod.NotEarlyStop.ordinal());
        Log.e("AAA", "status" + status);
    }

    private void sendTextMsg(String hello) {
        final Message mMessgae = getBaseSendMessage(MsgType.TEXT_SEND);
        TextMsgBody mTextMsgBody = new TextMsgBody();
        mTextMsgBody.setMessage(hello);
        mMessgae.setBody(mTextMsgBody);
        //开始发送
        dataList.add(mMessgae);
        mRvChat.scrollToPosition(chatAdapter.getItemCount() - 1);
        chatAdapter.notifyDataSetChanged();
        autoReceive();
    }

    private void receiveTextMsg(String hello) {
        final Message mMessgae = getBaseSendMessage(MsgType.TEXT_RECEIVE);
        TextMsgBody mTextMsgBody = new TextMsgBody();
        mTextMsgBody.setMessage(hello);
        mMessgae.setBody(mTextMsgBody);
        dataList.add(mMessgae);
        mRvChat.scrollToPosition(chatAdapter.getItemCount() - 1);
        chatAdapter.notifyDataSetChanged();
    }

    private void sendImageMessage(final int media) {
        final Message mMessgae = getBaseSendMessage(MsgType.IMAGE_SEND);
        ImageMsgBody mImageMsgBody = new ImageMsgBody();
        mImageMsgBody.setThumbUrl(media);
        mMessgae.setBody(mImageMsgBody);
        dataList.add(mMessgae);
        mRvChat.scrollToPosition(chatAdapter.getItemCount() - 1);
        chatAdapter.notifyDataSetChanged();
        autoReceive();
    }

    private Message getBaseSendMessage(int msgType) {
        Message mMessgae = new Message();
        mMessgae.setUuid(UUID.randomUUID() + "");
        mMessgae.setSentTime(System.currentTimeMillis());
        mMessgae.setSentStatus(MsgSendStatus.SENDING);
        mMessgae.setMsgType(msgType);
        return mMessgae;
    }

    private void autoReceive() {
        new Handler().postDelayed(() -> {
            int ran = random.nextInt(21);
            String[] autoReceiveMsg = getResources().getStringArray(R.array.autoReceiveMsg);
            receiveTextMsg(autoReceiveMsg[ran]);
        }, 1000);
    }
}